"""
-------------------------------
- File_Name: ormUtil.py
- Date: 2025/2/15
- Author: yangzhide
- Email: xxzjyzd@126.com
- Description: 数据库ORM增删改查
-------------------------------
"""

from typing import Type, Any
from tortoise import models


class OrmCRUD:
    def __init__(self, model: Type[models.Model]):
        self.model = model

    async def add(self, **kwargs) -> Any:
        """通用新增函数
        异常有全局异常处理器处理
        """
        result = await self.model.create(**kwargs)
        return await result.to_dict()

    async def delete(self, id: int | str) -> Any:
        """通用删除函数,条件：id
        对象不存在返回 None
        删除成功返回空 {}
        """
        obj = await self.model.get_or_none(id=id)
        if obj is None:
            return None
        await self.model.filter(id=id).delete()
        return {}

    async def update(self, data: Any, id: int) -> Any:
        """通用更新函数，条件id
        对象不存在返回 None
        更新成功返回更新后对象
        """
        obj = await self.model.get_or_none(id=id)
        if obj is not None:
            update_fields = data.dict(exclude_unset=True)  # 过滤掉不更新的字段，防止给默认值
            await obj.update_from_dict(update_fields).save()
            result = await self.model.get(id=id)  # 返回最新学生信息
            return await result.to_dict()

        else:
            return None

    async def get_or_none(self, id) -> Any:
        """通用查询函数，条件id
        对象不存在返回 None
        否则返回该对象
        """
        result = await self.model.get_or_none(id=id)
        if result is None:
            return None
        return await result.to_dict()

    async def filter(
            self,
            current: int = 1,
            size: int = 10,
            order: list[str] | None = None,
            include_fields: list[str] | None = None,
            exclude_fields: list[str] | None = None,
            **kwargs) -> Any:
        """通用过滤查询函数：不存在或异常时抛出错误
            当前页
            当前页条目数
            排序字段
            其他查询条件
        """
        order = [] if order is None else order
        query = self.model.filter(**kwargs)
        total = await query.count()
        result = await query.offset((current - 1) * size).limit(size).order_by(*order)
        data = [await r.to_dict(include_fields,exclude_fields) for r in result]
        return total, data
